package com.glkj.vipsystem.modules.report.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.glkj.vipsystem.common.utils.Constant;
import com.glkj.vipsystem.common.utils.PageUtils;
import com.glkj.vipsystem.common.utils.Query;
import com.glkj.vipsystem.common.utils.R;
import com.glkj.vipsystem.entity.ao.VipCardAO;
import com.glkj.vipsystem.entity.ao.VipCardRecordAO;
import com.glkj.vipsystem.modules.sys.controller.AbstractController;
import com.glkj.vipsystem.service.IVipCardRecordService;
import com.glkj.vipsystem.service.IVipCardService;
import com.glkj.vipsystem.service.impl.StatService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 统计报表
 *
 * @author limuchan
 */
@RequestMapping("/report")
@RestController
public class ReportController extends AbstractController {

    @Resource
    private IVipCardRecordService vipCardRecordService;
    @Resource
    private IVipCardService vipCardService;
    @Resource
    private StatService statService;

    /**
     * 列表
     */
    @RequestMapping(value = "/vipCardRecord/list")
    @RequiresPermissions({"report:vipCardRecord:all"})
    public R vipCardRecordList(@RequestParam Map<String, Object> params) {
        Wrapper<VipCardRecordAO> wrapper = getWrapper(params);
        wrapper.setSqlSelect("*,(select company_name from t_company where id = t_vip_card_record.company_id) as company_name" +
                ",(select shop_name from t_shop where id = t_vip_card_record.shop_id) as shop_name");
        Page<VipCardRecordAO> page = vipCardRecordService.selectPage(
                new Query<VipCardRecordAO>(params).getPage(), wrapper
        );
        List<VipCardRecordAO> records = page.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            for (VipCardRecordAO record : records) {
                if (record.getBalanceChange().compareTo(BigDecimal.ZERO) < 0) {
                    record.setBalanceChange(BigDecimal.ZERO.subtract(record.getBalanceChange()));
                }
            }
        }
        return R.ok().put("page", new PageUtils(page));
    }

    /**
     * 充值消费数据
     */
    @RequestMapping(value = "/vipCardRecord/getData")
    @RequiresPermissions({"report:vipCardRecord:all"})
    public R getData(@RequestParam Map<String, Object> params) {
        Wrapper<VipCardRecordAO> wrapper = getWrapper(params);
        String type = (String) params.get("type");
        if (StringUtils.isNotBlank(type)) {
            if (Integer.parseInt(type) == 1) {
                wrapper.setSqlSelect("sum(change_fee) as chargeAmount");
            } else if (Integer.parseInt(type) == 2) {
                wrapper.setSqlSelect("sum(balance_change) as costAmount");
            }
        } else {
            wrapper.setSqlSelect("sum(change_fee) as chargeAmount");
        }
        Map<String, Object> data = vipCardRecordService.selectMap(
                wrapper
        );

        if (data == null) {
            data = new HashMap<>();
        }
        BigDecimal costAmount = (BigDecimal) data.get("costAmount");
        if (costAmount != null) {
            costAmount = BigDecimal.ZERO.subtract(costAmount);
            data.put("costAmount", costAmount);
        }
        data.putIfAbsent("chargeAmount", 0);
        data.putIfAbsent("costAmount", 0);
        return R.ok().put("data", data);
    }

    private Wrapper<VipCardRecordAO> getWrapper(Map<String, Object> params) {
        String memberInfo = (String) params.get("memberInfo");
        String time = (String) params.get("time");
        String cardType = (String) params.get("cardType");
        String type = (String) params.get("type");
        String companyName = (String) params.get("companyName");
        Wrapper<VipCardRecordAO> wrapper = new EntityWrapper<VipCardRecordAO>();
        wrapper.orderBy("id desc");
        // 充值 消费类型
        if (StringUtils.isNotBlank(type)) {
            wrapper.eq("change_type", type);
        } else {
            wrapper.eq("change_type", Constant.VipCardRecordChangeType.SYSTEM.getValue());
        }
        // 数据权限控制
        if (isCompanyRole()) {
            // 公司管理员
            String username = getUser().getUsername();
            wrapper.where("company_id = (select id from t_company where `username` = '" + username + "')");

        } else if (isEmployeeRole()) {
            // 员工
            String username = getUser().getUsername();
            wrapper.where("company_id = (select company_id from t_employee where `username` = '" + username + "')");
        }
        if (StringUtils.isNotBlank(companyName)) {
            wrapper.where("company_id in (select id from t_company where company_name like '%" + companyName + "%')");
        }

        if (StringUtils.isNotBlank(memberInfo)) {
            wrapper.where("(member_name like '%" + memberInfo + "%' or member_mobile like '%" + memberInfo + "%'"
                    + " or card_no like '%" + memberInfo + "%')");
        }
        if (StringUtils.isNotBlank(cardType)) {
            wrapper.eq("card_type", cardType);
        }
        if (StringUtils.isNotBlank(time) && time.contains("~")) {
            String[] timeRange = time.split("~");
            wrapper.ge("create_time", timeRange[0].trim());
            wrapper.le("create_time", timeRange[1].trim() + " 23:59:59");
        }
        return wrapper;
    }

    /**
     * 会员卡列表
     */
    @RequestMapping(value = "/vipCard/list")
    @RequiresPermissions(value = {"report:vipCard:all"})
    public R vipCardList(@RequestParam Map<String, Object> params) {
        Wrapper<VipCardAO> wrapper = getVipCardWrapper(params);
        wrapper.orderBy("id desc");
        wrapper.setSqlSelect("*,(select company_name from t_company where id = t_vip_card.company_id) as company_name" +
                ",(select shop_name from t_shop where id = t_vip_card.shop_id) as shop_name");

        Page<VipCardAO> page = vipCardService.selectPage(
                new Query<VipCardAO>(params).getPage(), wrapper
        );
        wrapper = getVipCardWrapper(params);
        wrapper.setSqlSelect("sum(card_fee) as totalAmount");
        Map<String, Object> totalAmount = vipCardService.selectMap(wrapper);
        if (totalAmount == null) totalAmount = new HashMap<>();
        return R.ok().put("page", new PageUtils(page)).put("totalAmount", totalAmount.getOrDefault("totalAmount", BigDecimal.ZERO));
    }

    private Wrapper<VipCardAO> getVipCardWrapper(Map<String, Object> params) {
        Wrapper<VipCardAO> wrapper = new EntityWrapper<VipCardAO>();
        String companyId = (String) params.get("companyId"); // 所属公司筛选
        String shopId = (String) params.get("shopId"); // 开卡店铺
        String memberInfo = (String) params.get("memberInfo"); // 会员姓名/电话搜索 /会员卡号
        String cardType = (String) params.get("cardType"); // 卡类型搜索
        String time = (String) params.get("time");
        // 数据权限控制
        if (isCompanyRole()) {
            // 公司管理员
            String username = getUser().getUsername();
            wrapper.where("company_id = (select id from t_company where `username` = '" + username + "')");
        } else if (isEmployeeRole()) {
            // 员工
            String username = getUser().getUsername();
            wrapper.where("shop_id = (select shop_id from t_employee where `username` = '" + username + "')");
        } else if (StringUtils.isNotBlank(companyId)) {
            wrapper.eq("company_id", companyId);
        }
        if (!isEmployeeRole() && StringUtils.isNotBlank(shopId)) {
            wrapper.eq("shop_id", shopId);
        }
        if (StringUtils.isNotBlank(memberInfo)) {
            wrapper.where("(member_name like '%" + memberInfo + "%' or member_mobile like '%" + memberInfo + "%'" +
                    " or card_no like '%" + memberInfo + "%')");
        }
        if (StringUtils.isNotBlank(cardType)) {
            wrapper.eq("card_type", cardType);
        }
        if (StringUtils.isNotBlank(time) && time.contains("~")) {
            String[] timeRange = time.split("~");
            wrapper.ge("create_time", timeRange[0].trim());
            wrapper.le("create_time", timeRange[1].trim() + " 23:59:59");
        }
        return wrapper;
    }

    /**
     * 销售统计图数据
     */
    @RequestMapping(value = "/stat/sale")
    @RequiresPermissions({"report:stat:sale"})
    public R statSale(@RequestParam Map<String, Object> params) {
        String time = (String) params.get("time");
        String start = "";
        String end = "";
        if (StringUtils.isNotBlank(time) && time.contains("~")) {
            String[] timeRange = time.split("~");
            start = timeRange[0].trim();
            end = timeRange[1].trim() + " 23:59:59";
        } else {
            // 获取最近30天的时间
            Date now = DateUtil.tomorrow();
            DateTime startTime = DateUtil.offset(now, DateField.DAY_OF_YEAR, -30);
            start = DateUtil.formatDate(startTime);
            end = DateUtil.formatDate(now);
        }
        Map<String, Object> data = new HashMap<>();
        List<Map> rows = statService.statSale(start, end);
        String[] columns = new String[]{"day", "num", "amount"};
        data.put("rows", rows);
        data.put("columns", columns);

        return R.ok().put("data", data);
    }

    /**
     * 收入统计图数据
     */
    @RequestMapping(value = "/stat/income")
    @RequiresPermissions({"report:stat:sale"})
    public R statIncome(@RequestParam Map<String, Object> params) {
        String time = (String) params.get("time");
        String start = "";
        String end = "";
        if (StringUtils.isNotBlank(time) && time.contains("~")) {
            String[] timeRange = time.split("~");
            start = timeRange[0].trim();
            end = timeRange[1].trim() + " 23:59:59";
        } else {
            // 获取最近30天的时间
            Date now = DateUtil.tomorrow();
            DateTime startTime = DateUtil.offset(now, DateField.DAY_OF_YEAR, -30);
            start = DateUtil.formatDate(startTime);
            end = DateUtil.formatDate(now);
        }
        Map<String, Object> orderChartData = new HashMap<>();
        List<Map> rows = statService.statIncomeOrder(start, end);
        String[] columns = new String[]{"day", "num", "amount"};
        orderChartData.put("rows", rows);
        orderChartData.put("columns", columns);

        Map<String, Object> vipChartData = new HashMap<>();
        List<Map> rows1 = statService.statIncomeVip(start, end);
        vipChartData.put("rows", rows1);
        vipChartData.put("columns", columns);

        return R.ok().put("orderChartData", orderChartData).put("vipChartData", vipChartData);
    }

}
